package com.seedeer.project.service.system.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.seedeer.common.constant.ParamConsts;
import com.seedeer.common.exception.CustomException;
import com.seedeer.framework.i18n.I18nConsts;
import com.seedeer.project.domain.entity.SysParam;
import com.seedeer.project.mapper.SysParamMapper;
import com.seedeer.project.service.system.ISysParamService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.io.Serializable;
import java.util.List;

/**
 * <p>
 * 系统参数 服务实现类
 * </p>
 *
 * @author wangqiang
 */
@Service
@CacheConfig(cacheNames = "bbc::sysParam")
public class SysParamServiceImpl extends ServiceImpl<SysParamMapper, SysParam> implements ISysParamService {

    @Autowired
    private SysParamMapper sysParamMapper;

    /**
     * 根据父参数查询所有子参,并作缓存
     *
     * @param parentCode 父参编码
     */
    @Override
    @Cacheable(key = "#parentCode", unless = "#result == null")
    public List<SysParam> findSubParam(String parentCode) {
        Assert.notNull(parentCode, "父参编码不能为空！");
        Wrapper<SysParam> wrapper = Wrappers.<SysParam>lambdaQuery()
                .eq(SysParam::getParentCode, parentCode)
                .orderByAsc(SysParam::getParamSort)
                .orderByAsc(SysParam::getId);
        return this.list(wrapper);
    }

    /**
     * 查询参数详情
     *
     * @param paramCode 参数编码
     */
    @Override
    public SysParam findParam(String paramCode) {
        Assert.notNull(paramCode, "参数编码不能为空！");
        Wrapper<SysParam> wrapper = Wrappers.<SysParam>lambdaQuery()
                .eq(SysParam::getParamCode, paramCode);
        return sysParamMapper.selectOne(wrapper);
    }

    /**
     * 更新系统参数的版本号
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(allEntries = true, beforeInvocation = true)
    public void updateVersionNum() {
        Wrapper<SysParam> wrapper = Wrappers.<SysParam>lambdaQuery()
                .eq(SysParam::getParamCode, ParamConsts.VERSION_NUM);
        SysParam sysParam = sysParamMapper.selectOne(wrapper);
        if (null != sysParam) {
            int num = Integer.parseInt(sysParam.getParamValue());
            sysParam.setParamValue(String.valueOf(++num));
            sysParamMapper.updateById(sysParam);
        }
    }

    /**
     * 校验系统编码的唯一性
     *
     * @param paramCode 系统编码
     */
    private void validUniqueParamCode(Integer id, String paramCode) {
        //校验参数编码是否已定义
        Wrapper<SysParam> wrapper = Wrappers.<SysParam>lambdaQuery()
                .eq(SysParam::getParamCode, paramCode);
        SysParam sysParam = sysParamMapper.selectOne(wrapper);
        if (null != sysParam && !sysParam.getId().equals(id)) {
            throw new CustomException(I18nConsts.EXISTS_CODE, paramCode);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean save(SysParam entity) {
        //校验参数编码是否已定义
        this.validUniqueParamCode(entity.getId(), entity.getParamCode());
        //更新版本号
        this.updateVersionNum();
        return super.save(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean update(SysParam entity, Wrapper<SysParam> updateWrapper) {
        //校验参数编码是否已定义
        this.validUniqueParamCode(entity.getId(), entity.getParamCode());
        //若更改的为父参数,则子参数也进行修正
        SysParam now = sysParamMapper.selectById(entity.getId());
        if (null == entity.getParentCode() && !StringUtils.equals(now.getParamCode(), entity.getParamCode())) {
            Wrapper<SysParam> wrapper = Wrappers.<SysParam>lambdaQuery()
                    .eq(SysParam::getParentCode, now.getParamCode());
            SysParam update = new SysParam();
            update.setParentCode(entity.getParamCode());
            sysParamMapper.update(update, wrapper);
        }
        //更新版本号
        this.updateVersionNum();
        return super.update(entity, updateWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeById(Serializable id) {
        SysParam sysParam = sysParamMapper.selectById(id);
        if (null != sysParam) {
            //删除父参数下的子参数
            if (StringUtils.isBlank(sysParam.getParentCode())) {
                Wrapper<SysParam> wrapper = Wrappers.<SysParam>lambdaQuery()
                        .eq(SysParam::getParentCode, sysParam.getParamCode());
                sysParamMapper.delete(wrapper);
            }
            //更新版本号
            this.updateVersionNum();
            return super.removeById(id);
        }
        return true;
    }
}
